#include <iostream>
#include <string>
#include <sstream>
using namespace std;

#include "Bitext.hh"
#include "Model.hh"

void ExpectedCounts::reset(SentencePair &pair){
  J = pair.source_ids.size();
  I = pair.target_ids.size();

  if(J > size())
    resize(J);
 
  for(int j = 0; j < J; j++){
    vector<double> &sub_v = operator[](j);
    if(I > sub_v.size())
      sub_v.resize(I);
    
    for(int i = 0; i < I; i++){
      sub_v[i] = 0.0;
    }
  }
}

void ExpectedCounts::print(){
  for(int i = 0; i < I; i++){
    cout << "i=" << i << "\t";
    for(int j = 0; j < J; j++){
      cout << operator[](j)[i] << " ";
    }
    cout << endl;
  }
  cout << flush;
}

double Model::viterbi(SentencePair &pair, bool verbose){
  return viterbi_inner(pair, verbose);  
}

void Model::get_expected_counts(Bitext &bitext, SentencePair &pair, ExpectedCounts &counts){
  // get raw counts.
  counts.reset(pair);
  get_raw_expected_counts(bitext, pair, counts);

  // apply weighted expectation?
  bool apply_weighted_expectation = true;
  double lambda = 0.9;
  if(apply_weighted_expectation && pair.is_labeled_training_example()){ // must be a labeled training example!
    for(int j = 0; j < pair.J; j++){
      for(int i = 0; i < pair.I; i++){
	counts[j][i] *= (1 - lambda);
	if(pair.alignment_labeling.find(std::pair<int, int>(j, i)) != pair.alignment_labeling.end()){
	  counts[j][i] += lambda;
	}
      }
    }
  }
}
